using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Text;

using Banshee.Base;
using Banshee.Sources;
using Banshee.MediaEngine;
using Banshee.Winforms;
using Banshee.Winforms.Controls;
using System.Windows.Forms;
namespace Banshee
{
    public enum RepeatMode
    {
        None,
        All,
        Single,
        ErrorHalt
    }
    public class PlaylistModel
    {

        public event EventHandler Updated;
        public event EventHandler Stopped;
        public event EventHandler Cleared;
        protected SortableBindingList<TrackInfo> _tracks = new SortableBindingList<TrackInfo>();
        public int Count()
        {
            return _tracks.Count;
        }
        public TimeSpan TotalDuration
        {
            get
            {
                return totalDuration;
            }
        }
        private TimeSpan totalDuration = new TimeSpan(0);
        public void AddTrack(TrackInfo track)
        {
            AddTrack(track, true);

        }
        public void AddTrack(TrackInfo track,bool raiseUpdate)
        {
            totalDuration += track.Duration;
            _tracks.Add(track);
            if (raiseUpdate)
            {
                RaiseUpdated(this, new EventArgs());
            }
        }
        public SortableBindingList<TrackInfo> Tracks
        {
            get { return _tracks; }
            set { _tracks = value; }
        }
        public void Clear()
        {
            _tracks.Clear();
        }
        public PlaylistModel()
        {
            SourceManager.ActiveSourceChanged += delegate(SourceEventArgs args)
            {
                ReloadSource();
            };

            PlayerEngineCore.EventChanged += delegate(object o, PlayerEngineEventArgs args)
            {
                switch (args.Event)
                {
                    case PlayerEngineEvent.StartOfStream:
                        return;
                }
            };
        }
        public void ClearModel()
        {
            totalDuration = new TimeSpan(0);
            _tracks.Clear();
            RaiseUpdated(this, new EventArgs());
        }
        private bool can_save_sort_id = true;
        bool reloading = false;
        TrackSource source = new TrackSource();

        public TrackSource Source
        {
            get { return source; }
            set { source = value; }
        }
        void reloadthread()
        {

            if (InterfaceElements.MainWindow != null)
            {
                InterfaceElements.MainWindow.BeginInvoke((MethodInvoker)delegate()
                {
                    if (!reloading)
                    {
                        //_tracks.Clear();
                        RaiseCleared(this, new EventArgs());
                        totalDuration = new TimeSpan(0);
                        lock (SourceManager.ActiveSource.TracksMutex)
                        {
                            source.Reload();
                            totalDuration = source.TotalDuration;
                            this.Tracks = source.Tracks;

                        }
                    }
                    total_count = _tracks.Count;
                    RaiseUpdated(this, new EventArgs());
                });
            }
        }
        public void ReloadSource()
        {
            ThreadAssist.Spawn(new System.Threading.ThreadStart(reloadthread), true);
        }
        private int total_count;
        private int scan_ref_count = 0;
        private static System.Drawing.Icon user_event_icon = IconThemeUtils.LoadIcon(ConfigureDefines.ICON_THEME_DIR + @"\user-home.png");
        private static readonly object user_event_mutex = new object();
        private void RaiseCleared(object sender, EventArgs e)
        {
            EventHandler handler = Cleared;
            if (handler != null)
                handler(sender, e);
        }
        private void RaiseUpdated(object o, EventArgs args)
        {
            EventHandler handler = Updated;
            if (handler != null)
                handler(o, args);
        }
        private DataGridViewRow currentRow;
        private DataGridViewRow nextRow;
        private TrackInfo currentTrack;
        public void PlayIter(string uri)
        {
            TrackInfo track = PathTreeInfo(uri);
            current_index = currentIndex(uri);
            currentTrack = track;
            PlayerEngineCore.OpenPlay(track);
            
        }
        public TrackInfo PathTreeInfo(string path)
        {
            TrackInfo pathtrackinfo = null;
            foreach (TrackInfo track in SourceManager.ActiveSource.Tracks)
            {
                if (track.Uri.ToString() == path)
                {
                    pathtrackinfo = track;
                    break;
                }
            }
            return pathtrackinfo;
        }
        TrackInfo selected_track;

        public TrackInfo SelectedTrack
        {
            get { return selected_track; }
            set { selected_track = value; }
        }
        int current_index = 0;
        private int currentIndex(string uri)
        {
            int rtn = 0;
            for (int i = 0; i < _tracks.Count; i++)
            {
                if (_tracks[i].Uri.ToString() == uri)
                    rtn = i;
            }
            return rtn;
        }
        private void ChangeDirection(bool forward)
        {
            //Cornel - Okay so now i need to get this working
            if (forward)
            {
                if (repeat == RepeatMode.All)
                {

                    TrackInfo track = _tracks[current_index+1]; 
                    selected_track = track;
                    //PlayerEngineCore.OpenPlay(track);
                    PlayIter(track.Uri.ToString());
                }
            }
            else
            {
                if (repeat == RepeatMode.All)
                {
                    int index = current_index - 1;
                    if (index >= 0)
                    {
                        TrackInfo track = _tracks[index]; 
                        selected_track = track;
                        //PlayerEngineCore.OpenPlay(track);
                        PlayIter(track.Uri.ToString());
                    }
                }
            }
        }
        DataGridViewRow playingIter;
        public void Advance()
        {
            ChangeDirection(true);
        }
        public void Regress()
        {
            ChangeDirection(false);
        }
        public void Continue()
        {
            Advance();
        }
        private RepeatMode repeat = RepeatMode.None;
        private bool shuffle = false;

        public RepeatMode Repeat
        {
            set
            {
                repeat = value;
            }

            get
            {
                return repeat;
            }
        }
        public bool Shuffle
        {
            set
            {
                shuffle = value;
            }

            get
            {
                return shuffle;
            }
        }
        
    }
}
